﻿using DocumentFormat.OpenXml.Drawing;
using Magicodes.ExporterAndImporter.Core;
using Mapster;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Mvc.Routing;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using NP.BPMReportPlatform.AuthorizationUserManager.Dtos;
using NP.BPMReportPlatform.DBHelper;
using NP.BPMReportPlatform.Entities.BPM_Business;
using NP.BPMReportPlatform.Entities.BPM_Business.Reports;
using NP.BPMReportPlatform.Entities.BPM_Platform;
using NP.BPMReportPlatform.Entities.BPM_Process;
using NP.BPMReportPlatform.Reports.CommonApprovalProcessReport.Dtos;
using NP.BPMReportPlatform.Utilities;
using NP.BPMReportPlatform.Utils;
using NP.BPMReportPlatform.YCLWLJGZSYC.Dto;
using NP.Enterprise.Utils.Http;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using RestSharp;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Users;

namespace NP.BPMReportPlatform.Reports.CommonApprovalProcessReport
{
    public class CommonApprovalProcessService : BPMReportPlatformAppService, ICommonApprovalProcessService
    {
        private readonly SqlSugarClient _db, _dbPlatform, _dbProcess, _dbEngine, _dbToDoCenter;
        private readonly IBPMUtilsAppService _bPMUtilsApp;
        private readonly INPRestHttpHelper _nPRestHttp;
        private readonly IConfiguration _configuration;

        public CommonApprovalProcessService(ISqlSugarAppService sqlSugarAppService, IBPMUtilsAppService bPMUtilsApp,
            INPRestHttpHelper nPRestHttp, IConfiguration configuration)
        {
            _db = sqlSugarAppService.GetBusinessInstance();
            _dbPlatform = sqlSugarAppService.GetPlatformInstance();
            _bPMUtilsApp = bPMUtilsApp;
            _dbProcess = sqlSugarAppService.GetProcessInstance();
            _dbEngine = sqlSugarAppService.GetEngineInstance();
            _dbToDoCenter = sqlSugarAppService.GetToDoCenterInstance();
            _nPRestHttp = nPRestHttp;
            _configuration = configuration;
        }

        /// <summary>
        /// 获取Queryable
        /// </summary>
        /// <returns></returns>
        /// <param name="input"></param>
        private ISugarQueryable<GetCommonApprovalProcessOutput> GetQueryable(GetCommonApprovalProcessInput input)
        {
            var currentUserId = Guid.Empty;
            if (!input.IsQueryAll)
            {
                var currentUserDto = _dbPlatform.Queryable<Users>().Where(x => x.WorkNumber.Equals(CurrentUser.UserName)).First();
                if (currentUserDto != null)
                {
                    currentUserId = currentUserDto.UserId;
                }
            }

            var configs = _db.Queryable<CommonApprovalProcessConfig>().Where(x => x.BTID == input.FlowType).ToList();
            var topicField = configs.GetConfigFiledCombine(FieldEnum.Topic);
            var text1Field = configs.GetConfigFiledCombine(FieldEnum.Text1);
            var text2Field = configs.GetConfigFiledCombine(FieldEnum.Text2);
            var text3Field = configs.GetConfigFiledCombine(FieldEnum.Text3);
            var text4Field = configs.GetConfigFiledCombine(FieldEnum.Text4);
            var text5Field = configs.GetConfigFiledCombine(FieldEnum.Text5);
            var text6Field = configs.GetConfigFiledCombine(FieldEnum.Text6);
            var text7Field = configs.GetConfigFiledCombine(FieldEnum.Text7);
            var text8Field = configs.GetConfigFiledCombine(FieldEnum.Text8);
            var text9Field = configs.GetConfigFiledCombine(FieldEnum.Text9);
            var text10Field = configs.GetConfigFiledCombine(FieldEnum.Text10);
            var text11Field = configs.GetConfigFiledCombine(FieldEnum.Text11);
            var text12Field = configs.GetConfigFiledCombine(FieldEnum.Text12);
            var text13Field = configs.GetConfigFiledCombine(FieldEnum.Text13);
            var text14Field = configs.GetConfigFiledCombine(FieldEnum.Text14);
            var text15Field = configs.GetConfigFiledCombine(FieldEnum.Text15);
            var text16Field = configs.GetConfigFiledCombine(FieldEnum.Text16);
            var text17Field = configs.GetConfigFiledCombine(FieldEnum.Text17);
            var text18Field = configs.GetConfigFiledCombine(FieldEnum.Text18);
            var text19Field = configs.GetConfigFiledCombine(FieldEnum.Text19);
            var text20Field = configs.GetConfigFiledCombine(FieldEnum.Text20);
            var listQueryable = _db.Queryable<CommonApprovalProcess, BusinessProcessesNew>((x, b) =>
                new JoinQueryInfos(JoinType.Inner, x.InstanceNumber == b.InstanceId))
                   .WhereIF(!input.IsQueryAll, (x, b) => x.AddUserId.Equals(currentUserId))
                   .WhereIF(input.BTID.Any(), (x, b) => input.BTID.Contains(b.BTID))
                   .WhereIF(!string.IsNullOrWhiteSpace(input.FlowType) && !input.BTID.Any(), (x, b) => b.BTID.Equals(input.FlowType))
                   .Select((x, b) =>
                   new GetCommonApprovalProcessOutput()
                   {
                       InstanceNumber = x.InstanceNumber,
                       Topic = b.ProcessTopic,
                       StartUserName = b.StartUserName,
                       StartTime = b.StartTime,
                       StatusName = b.ProcessStatusName,
                       StatusCode = b.ProcessStatusCode,
                       Text1 = x.Text1,
                       Text2 = x.Text2,
                       Text3 = x.Text3,
                       Text4 = x.Text4,
                       Text5 = x.Text5,
                       Text6 = x.Text6,
                       Text7 = x.Text7,
                       Text8 = x.Text8,
                       Text9 = x.Text9,
                       Text10 = x.Text10,
                       Text11 = x.Text11,
                       Text12 = x.Text12,
                       Text13 = x.Text13,
                       Text14 = x.Text14,
                       Text15 = x.Text15,
                       Text16 = x.Text16,
                       Text17 = x.Text17,
                       Text18 = x.Text18,
                       Text19 = x.Text19,
                       Text20 = x.Text20,
                       TextArea1 = x.TextArea1,
                       TextArea2 = x.TextArea2,
                       TextArea3 = x.TextArea3,
                       TextArea4 = x.TextArea4,
                   }).MergeTable()
                   .Select(x => new GetCommonApprovalProcessOutput
                   {
                       InstanceNumber = x.InstanceNumber,
                       Topic = CommonApprovalSqlFuncExtension.CustomFiledDisplay(topicField, "Topic"),
                       StartUserName = x.StartUserName,
                       StartTime = x.StartTime,
                       StatusName = x.StatusName,
                       StatusCode = x.StatusCode,
                       Text1 = CommonApprovalSqlFuncExtension.CustomFiledDisplay(text1Field, "Text1"),
                       Text2 = CommonApprovalSqlFuncExtension.CustomFiledDisplay(text2Field, "Text2"),
                       Text3 = CommonApprovalSqlFuncExtension.CustomFiledDisplay(text3Field, "Text3"),
                       Text4 = CommonApprovalSqlFuncExtension.CustomFiledDisplay(text4Field, "Text4"),
                       Text5 = CommonApprovalSqlFuncExtension.CustomFiledDisplay(text5Field, "Text5"),
                       Text6 = CommonApprovalSqlFuncExtension.CustomFiledDisplay(text6Field, "Text6"),
                       Text7 = CommonApprovalSqlFuncExtension.CustomFiledDisplay(text7Field, "Text7"),
                       Text8 = CommonApprovalSqlFuncExtension.CustomFiledDisplay(text8Field, "Text8"),
                       Text9 = CommonApprovalSqlFuncExtension.CustomFiledDisplay(text9Field, "Text9"),
                       Text10 = CommonApprovalSqlFuncExtension.CustomFiledDisplay(text10Field, "Text10"),
                       Text11 = CommonApprovalSqlFuncExtension.CustomFiledDisplay(text11Field, "Text11"),
                       Text12 = CommonApprovalSqlFuncExtension.CustomFiledDisplay(text12Field, "Text12"),
                       Text13 = CommonApprovalSqlFuncExtension.CustomFiledDisplay(text13Field, "Text13"),
                       Text14 = CommonApprovalSqlFuncExtension.CustomFiledDisplay(text14Field, "Text14"),
                       Text15 = CommonApprovalSqlFuncExtension.CustomFiledDisplay(text15Field, "Text15"),
                       Text16 = CommonApprovalSqlFuncExtension.CustomFiledDisplay(text16Field, "Text16"),
                       Text17 = CommonApprovalSqlFuncExtension.CustomFiledDisplay(text16Field, "Text17"),
                       Text18 = CommonApprovalSqlFuncExtension.CustomFiledDisplay(text16Field, "Text18"),
                       Text19 = CommonApprovalSqlFuncExtension.CustomFiledDisplay(text16Field, "Text19"),
                       Text20 = CommonApprovalSqlFuncExtension.CustomFiledDisplay(text16Field, "Text20"),
                       TextArea1 = x.TextArea1,
                       TextArea2 = x.TextArea2,
                       TextArea3 = x.TextArea3,
                       TextArea4 = x.TextArea4,
                   });

            listQueryable = listQueryable.MergeTable().AddQueryForEach(input.SearchItems);

            return listQueryable.OrderBy(x => x.StartTime, OrderByType.Desc);
        }

        public async Task<GetConfigsOutput> GetConfigs(string btid)
        {
            var query = await _db.Queryable<CommonApprovalProcessConfig, CommonApprovalProcessConfigHeader>(
                (a, b) => a.BTID == b.BTID).Where((a, b) => a.BTID == btid && b.IsEnable)
                .Select((a, b) => new { a, b }).ToListAsync();

            var res = new GetConfigsOutput
            {
                configList = query.Select(x => x.a).OrderBy(x => x.SortNum).ToList(),
                header = query.Select(x => x.b).FirstOrDefault()
            };

            return res;
        }

        /// <summary>
        /// 查询数据
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PagedResultDto<GetCommonApprovalProcessOutput>> GetAllAsync(GetCommonApprovalProcessInput input)
        {
            RefAsync<int> totalCount = 0;

            var listQueryable = GetQueryable(input);

            var listViewDto = await listQueryable.ToPageListAsync(input.PageIndex, input.PageSize, totalCount);

            var userDto = await _dbPlatform.Queryable<Users>().Where(x => x.WorkNumber.Equals(CurrentUser.UserName)).SingleAsync();

            listViewDto.ForEach(x => x.Url = _bPMUtilsApp.GetProcessUrl(x.InstanceNumber, userDto.UserId.ToString()));

            //返回结果
            return new PagedResultDto<GetCommonApprovalProcessOutput>()
            {
                TotalCount = totalCount,
                Items = listViewDto
            };
        }

        /// <summary>
        /// 导出数据
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<IWorkbook> ExportAsync(GetCommonApprovalProcessInput input)
        {
            var listQueryable = GetQueryable(input);
            var list = await listQueryable.ToListAsync();
            var workbook = new XSSFWorkbook();
            if (list.Any())
            {
                var columns = new List<string>();

                var configs = await GetConfigs(input.FlowType);
                configs.configList = configs.configList.Where(x => x.IsShowColumn).ToList();
                foreach ( var config in configs.configList)
                {
                    columns.Add(config.Field);
                }

                var sheet = workbook.CreateSheet("Sheet1");
                sheet.DisplayGridlines = true;
                IRow row = sheet.CreateRow(0); // 添加表头
                IFont font1 = workbook.CreateFont();
                font1.Boldweight = (short)FontBoldWeight.Bold;
                ICellStyle style1 = workbook.CreateCellStyle();
                style1.SetFont(font1);
                style1.VerticalAlignment = NPOI.SS.UserModel.VerticalAlignment.Center;
                style1.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center;
                style1.BorderBottom = BorderStyle.Thin;
                style1.BorderLeft = BorderStyle.Thin;
                style1.BorderRight = BorderStyle.Thin;
                style1.BorderTop = BorderStyle.Thin;
                for (var i = 0; i < columns.Count; i++)
                {
                    sheet.SetColumnWidth(i, 15 * 256);
                    row.CreateCell(i).SetCellValue(columns[i]);
                    row.GetCell(i).CellStyle = style1;
                }

                for (int i = 0; i < list.Count; i++)
                {
                    IRow rowtemp = sheet.CreateRow(i + 1);
                    var index = 0;
                    foreach (var config in configs.configList)
                    {
                        rowtemp.CreateCell(index).SetCellValue(FillData(list[i], config.SortIndex));
                        index++;
                    }
                }
            }
            return workbook;
        }
        private string FillData(GetCommonApprovalProcessOutput row, int index)
        {
            return index switch
            {
                1 => row.Text1,
                2 => row.Text2,
                3 => row.Text3,
                4 => row.Text4,
                5 => row.Text5,
                6 => row.Text6,
                7 => row.Text7,
                8 => row.Text8,
                9 => row.Text9,
                10 => row.Text10,
                11 => row.Text11,
                12 => row.Text12,
                13 => row.Text13,
                14 => row.Text14,
                15 => row.Text15,
                16 => row.Text16,
                17 => row.Text17,
                18 => row.Text18,
                19 => row.Text19,
                20 => row.Text20,
                101 => row.TextArea1,
                102 => row.TextArea2,
                103 => row.TextArea3,
                104 => row.TextArea4,
                1001 => row.InstanceNumber,
                1002 => row.Topic,
                1003 => row.StartUserName,
                1004 => row.StartTime.ToString(DateFormatHelper.DateTimeFormat),
                1005 => row.StatusName,
                _ => "",
            };
        }


        #region 配置维护

        public async Task AddOrUpdateConfig(CommonApprovalProcessConfig config)
        {
            if (config == null) throw new ArgumentNullException("无效数据");

            // 新增
            if (config.Id == null || config.Id == Guid.Empty)
            {
                var entity = new CommonApprovalProcessConfig
                {
                    Field = config.Field,
                    IsSearchItem = config.IsSearchItem,
                    IsAccurate = config.IsAccurate,
                    SortIndex = config.SortIndex,
                    FieldType = config.FieldType,
                    SortNum = config.SortNum,
                    SelectItems = config.SelectItems,
                    Id = Guid.NewGuid(),
                    BTID = config.BTID,
                    FieldCombine = config.FieldCombine,
                    IsShowColumn = config.IsShowColumn,
                    ColumnWidth = config.ColumnWidth,
                };
                await _db.Insertable(config).ExecuteCommandAsync();
            }
            else
            {
                // 修改
                var entity = await _db.Queryable<CommonApprovalProcessConfig>().FirstAsync(x => x.Id == config.Id);
                if (entity == null)
                {
                    throw new Exception("未找到数据");
                }
                entity.Field = config.Field;
                entity.IsSearchItem = config.IsSearchItem;
                entity.IsAccurate = config.IsAccurate;
                entity.SortIndex = config.SortIndex;
                entity.FieldType = config.FieldType;
                entity.SortNum = config.SortNum;
                entity.SelectItems = config.SelectItems;
                entity.FieldCombine = config.FieldCombine;
                entity.IsShowColumn = config.IsShowColumn;
                entity.ColumnWidth = config.ColumnWidth;
                await _db.Updateable(entity).ExecuteCommandAsync();
            }
        }

        public async Task<PagedResultDto<CommonApprovalProcessConfig>> GetConfigPageList(CommonApprovalProcessConfigInput input)
        {
            RefAsync<int> totalCount = 0;
            var res = await _db.Queryable<CommonApprovalProcessConfig, CommonApprovalProcessConfigHeader>(
                (a, b) => a.BTID == b.BTID)
                .WhereIF(!string.IsNullOrEmpty(input.BTID), (a, b) => a.BTID == input.BTID)
                .OrderBy((a, b) => a.BTID).OrderBy(a => a.SortNum)
                .Select((a, b) => a).ToPageListAsync(input.PageIndex, input.PageSize, totalCount);

            return new PagedResultDto<CommonApprovalProcessConfig>()
            {
                TotalCount = totalCount,
                Items = res
            };
        }

        public async Task DeleteConfig(Guid id)
        {
            await _db.Deleteable<CommonApprovalProcessConfig>().Where(x => x.Id == id).ExecuteCommandAsync();
        }

        #endregion

        #region 配置主表

        private ISugarQueryable<CommonApprovalProcessConfigHeaderDto> GetHeaderQueryable(CommonApprovalProcessConfigHeaderInput input)
        {
            var listQueryable = _dbProcess.Queryable<Processes, ProcessResponsible>((a, b) => a.ProcessId == b.ProcessId);
            var headers = _db.Queryable<CommonApprovalProcessConfigHeader>().AS("BPM_Business.CommonApprovalProcessConfigHeader");
            var res = listQueryable.InnerJoin(headers, (a, b, c) => a.BTID == c.BTID)
                .WhereIF(!string.IsNullOrEmpty(input.Name), (a, b, c) => a.Name.Contains(input.Name))
                .WhereIF(!string.IsNullOrEmpty(input.BTID), (a, b, c) => a.BTID.Contains(input.BTID))
                .WhereIF(!string.IsNullOrEmpty(input.Developer), (a, b, c) => b.Developer.Contains(input.Developer))
                .Select((a, b, c) => new CommonApprovalProcessConfigHeaderDto
                {
                    Id = c.Id,
                    BTID = c.BTID,
                    Name = a.Name,
                    Developer = b.Developer,
                    CreateTime = c.CreateTime,
                    IsEnable = c.IsEnable,
                    RelationBTIDs = c.RelationBTIDs,
                });

            return res;
        }

        /// <summary>
        /// 查询数据
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PagedResultDto<CommonApprovalProcessConfigHeaderDto>> GetHeaderAllAsync(CommonApprovalProcessConfigHeaderInput input)
        {
            RefAsync<int> totalCount = 0;

            var listQueryable = GetHeaderQueryable(input);

            var listViewDto = await listQueryable.ToPageListAsync(input.PageIndex, input.PageSize, totalCount);

            //返回结果
            return new PagedResultDto<CommonApprovalProcessConfigHeaderDto>()
            {
                TotalCount = totalCount,
                Items = listViewDto
            };
        }

        public async Task<List<CommonApprovalProcessConfigHeaderDto>> ExportHeaderExcel(CommonApprovalProcessConfigHeaderInput input)
        {
            var data = GetHeaderQueryable(input);
            return await data.ToListAsync();
        }

        public async Task HeaderAddOrUpdateConfig(CommonApprovalProcessConfigHeader header)
        {
            if (header == null) throw new ArgumentNullException("无效数据");

            if (string.IsNullOrWhiteSpace(header.BTID))
            {
                throw new Exception("请输入BTID");
            }

            var process = await _dbProcess.Queryable<Processes>().FirstAsync(x => x.BTID == header.BTID);
            if (process == null)
            {
                throw new Exception("BTID不存在");
            }

            // 新增
            if (header.Id == null || header.Id == Guid.Empty)
            {
                if (_db.Queryable<CommonApprovalProcessConfigHeader>().Any(x => x.BTID == header.BTID))
                {
                    throw new Exception("数据已存在");
                }

                var entity = new CommonApprovalProcessConfigHeader
                {
                    Id = Guid.NewGuid(),
                    BTID = header.BTID,
                    CreateTime = DateTime.Now,
                    IsEnable = header.IsEnable,
                };
                await _db.Insertable(entity).ExecuteCommandAsync();
            }
            else
            {
                if (_db.Queryable<CommonApprovalProcessConfigHeader>().Any(x => x.BTID == header.BTID && x.Id != header.Id))
                {
                    throw new Exception("数据已存在");
                }

                var entity = await _db.Queryable<CommonApprovalProcessConfigHeader>().FirstAsync(x => x.Id == header.Id);
                if (entity == null)
                {
                    throw new Exception("未找到数据");
                }

                try
                {
                    _db.BeginTran();

                    var configs = _db.Queryable<CommonApprovalProcessConfig>().Where(x => x.BTID == entity.BTID).ToList();
                    if (configs.Any())
                    {
                        configs.ForEach(x =>
                        {
                            x.BTID = header.BTID;
                        });
                        _db.Updateable(configs).ExecuteCommand();
                    }

                    entity.BTID = header.BTID;
                    entity.IsEnable = header.IsEnable;
                    entity.RelationBTIDs = header.RelationBTIDs;
                    _db.Updateable(entity).ExecuteCommand();

                    _db.CommitTran();
                }
                catch(Exception ex)
                {
                    _db.RollbackTran();
                    throw new Exception(ex.Message);
                }
            }
        }

        public async Task DeleteHeader(string BTID)
        {
            if (string.IsNullOrWhiteSpace(BTID))
            {
                throw new Exception("未找到数据");
            }

            try
            {
                _db.BeginTran();
                await _db.Deleteable<CommonApprovalProcessConfigHeader>().Where(x => x.BTID == BTID).ExecuteCommandAsync();
                await _db.Deleteable<CommonApprovalProcessConfig>().Where(x => x.BTID == BTID).ExecuteCommandAsync();
                await _db.Deleteable<CommonApprovalProcessSubDataConfig>().Where(x => x.BTID == BTID).ExecuteCommandAsync();
                await _db.Deleteable<CommonApprovalProcessSubDataDetailConfig>().Where(x => x.BTID == BTID).ExecuteCommandAsync();
                _db.CommitTran();
            }
            catch(Exception ex)
            {
                _db.RollbackTran();
                throw new Exception(ex.Message);
            }
        }

        #endregion

        #region 子表配置

        private ISugarQueryable<CommonApprovalProcessSubDataConfig> GetSubDataQueryable(CommonApprovalProcessConfigHeaderInput input)
        {
            var listQueryable = _db.Queryable<CommonApprovalProcessSubDataConfig>()
                .Where(x => x.BTID.Contains(input.BTID)).OrderBy(x => x.SortNum, OrderByType.Asc);

            return listQueryable;
        }

        /// <summary>
        /// 查询数据
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PagedResultDto<CommonApprovalProcessSubDataConfig>> GetSubDataAllAsync(CommonApprovalProcessConfigHeaderInput input)
        {
            RefAsync<int> totalCount = 0;

            var listQueryable = GetSubDataQueryable(input);

            var listViewDto = await listQueryable.ToPageListAsync(input.PageIndex, input.PageSize, totalCount);

            //返回结果
            return new PagedResultDto<CommonApprovalProcessSubDataConfig>()
            {
                TotalCount = totalCount,
                Items = listViewDto
            };
        }

        public async Task AddOrUpdateSubData(CommonApprovalProcessSubDataConfig config)
        {
            if (config == null) throw new ArgumentNullException("无效数据");

            // 新增
            if (config.Id == null || config.Id == Guid.Empty)
            {
                var entity = new CommonApprovalProcessSubDataConfig
                {
                    BTID = config.BTID,
                    ButtonName = config.ButtonName,
                    ModalX = config.ModalX,
                    ModalY = config.ModalY,
                    ModalTitle = config.ModalTitle,
                    Id = Guid.NewGuid(),
                    IsEnable = config.IsEnable,
                    Url = config.Url,
                    ExportUrl = config.ExportUrl,
                    SortNum = config.SortNum,
                    CreateTime = DateTime.Now,
                };
                await _db.Insertable(config).ExecuteCommandAsync();
            }
            else
            {
                // 修改
                var entity = await _db.Queryable<CommonApprovalProcessSubDataConfig>().FirstAsync(x => x.Id == config.Id);
                if (entity == null)
                {
                    throw new Exception("未找到数据");
                }
                entity.BTID = config.BTID;
                entity.ButtonName = config.ButtonName;
                entity.ModalX = config.ModalX;
                entity.ModalY = config.ModalY;
                entity.ModalTitle = config.ModalTitle;
                entity.IsEnable = config.IsEnable;
                entity.Url = config.Url;
                entity.ExportUrl = config.ExportUrl;
                entity.SortNum = config.SortNum;
                await _db.Updateable(entity).ExecuteCommandAsync();
            }
        }

        public async Task DeleteSubData(Guid Id)
        {
            if (Id == Guid.Empty)
            {
                throw new Exception("未找到数据");
            }

            try
            {
                _db.BeginTran();
                await _db.Deleteable<CommonApprovalProcessSubDataConfig>().Where(x => x.Id == Id).ExecuteCommandAsync();
                await _db.Deleteable<CommonApprovalProcessSubDataDetailConfig>().Where(x => x.SubDataId == Id).ExecuteCommandAsync();
                _db.CommitTran();
            }
            catch (Exception ex)
            {
                _db.RollbackTran();
                throw new Exception(ex.Message);
            }
        }

        private ISugarQueryable<CommonApprovalProcessSubDataDetailConfig> GetSubDataDetailQueryable(CommonApprovalProcessConfigHeaderInput input)
        {
            var listQueryable = _db.Queryable<CommonApprovalProcessSubDataDetailConfig>()
                .Where(x => x.SubDataId == input.SubDataId).OrderBy(x => x.SortNum, OrderByType.Asc);

            return listQueryable;
        }

        /// <summary>
        /// 查询数据
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PagedResultDto<CommonApprovalProcessSubDataDetailConfig>> GetSubDataDetailAllAsync(CommonApprovalProcessConfigHeaderInput input)
        {
            RefAsync<int> totalCount = 0;

            var listQueryable = GetSubDataDetailQueryable(input);

            var listViewDto = await listQueryable.ToPageListAsync(input.PageIndex, input.PageSize, totalCount);

            //返回结果
            return new PagedResultDto<CommonApprovalProcessSubDataDetailConfig>()
            {
                TotalCount = totalCount,
                Items = listViewDto
            };
        }

        public async Task AddOrUpdateSubDataDetail(CommonApprovalProcessSubDataDetailConfig config)
        {
            if (config == null) throw new ArgumentNullException("无效数据");

            // 新增
            if (config.Id == null || config.Id == Guid.Empty)
            {
                var entity = new CommonApprovalProcessSubDataDetailConfig
                {
                    SubDataId = config.SubDataId,
                    BTID = config.BTID,
                    Field = config.Field,
                    Name = config.Name,
                    FieldType = config.FieldType,
                    IsAccurate = config.IsAccurate,
                    SortNum = config.SortNum,
                    Id = Guid.NewGuid(),
                    SelectItems = config.SelectItems,
                    IsSearchItem = config.IsSearchItem,
                    IsShowColumn = config.IsShowColumn,
                    IsForeignKey = config.IsForeignKey,
                    ColumnWidth = config.ColumnWidth,
                };
                await _db.Insertable(config).ExecuteCommandAsync();
            }
            else
            {
                // 修改
                var entity = await _db.Queryable<CommonApprovalProcessSubDataDetailConfig>().FirstAsync(x => x.Id == config.Id);
                if (entity == null)
                {
                    throw new Exception("未找到数据");
                }
                entity.BTID = config.BTID;
                entity.SubDataId = config.SubDataId;
                entity.Field = config.Field;
                entity.Name = config.Name;
                entity.FieldType = config.FieldType;
                entity.IsAccurate = config.IsAccurate;
                entity.SortNum = config.SortNum;
                entity.SelectItems = config.SelectItems;
                entity.IsShowColumn = config.IsShowColumn;
                entity.IsSearchItem = config.IsSearchItem;
                entity.IsForeignKey = config.IsForeignKey;
                entity.ColumnWidth = config.ColumnWidth;
                await _db.Updateable(entity).ExecuteCommandAsync();
            }
        }

        public async Task DeleteSubDataDetail(Guid Id)
        {
            if (Id == Guid.Empty)
            {
                throw new Exception("未找到数据");
            }

            await _db.Deleteable<CommonApprovalProcessSubDataDetailConfig>().Where(x => x.Id == Id).ExecuteCommandAsync();
        }

        /// <summary>
        /// 获取BTID所有子表配置
        /// </summary>
        /// <param name="BTID"></param>
        /// <returns></returns>
        public async Task<List<CommonApprovalProcessSubDataConfig>> GetSubDataConfigs(string BTID)
        {
            var subDatas = await _db.Queryable<CommonApprovalProcessSubDataConfig>()
                .Where(x => x.BTID == BTID && x.IsEnable).OrderBy(x => x.SortNum, OrderByType.Asc).ToListAsync();
            var subDataIds = subDatas.Select(x => x.Id).ToList();
            var subDataDetails = await _db.Queryable<CommonApprovalProcessSubDataDetailConfig>()
                .Where(x => subDataIds.Contains(x.SubDataId)).ToListAsync();

            foreach (var subData in subDatas)
            {
                subData.DetailList = subDataDetails.Where(x => x.SubDataId == subData.Id)
                    .OrderBy(x => x.SortNum).ToList();
            }

            return subDatas;
        }

        #endregion

        /// <summary>
        /// 获取子表数据
        /// </summary>
        /// <returns></returns>
        public async Task<object> SearchSubDataList(GetCommonApprovalProcessInput input)
        {
            if (input == null || string.IsNullOrEmpty(input.Url))
            {
                throw new Exception("传参错误");
            }

            var resData = new Dictionary<string, object>
            {
                { "PageIndex", input.PageIndex },
                { "PageSize", input.PageSize }
            };
            if (input.SearchItems != null && input.SearchItems.Any())
            {
                foreach (var item in input.SearchItems)
                {
                    if (resData.ContainsKey(item.Field))
                    {
                        continue;
                    }

                    if (item.FieldType?.ToLower() == "date")
                    {
                        if (!string.IsNullOrEmpty(item.StartTime) && !string.IsNullOrEmpty(item.EndTime) &&
                        DateTime.TryParse(item.StartTime, out DateTime StartTime) && DateTime.TryParse(item.EndTime, out DateTime EndTime))
                        {
                            resData.Add(item.Field, new List<DateTime>() { StartTime, EndTime });
                        }
                    }
                    else if (item.FieldType?.ToLower() == "select-multiple")
                    {
                        if (item.SearchObjArr != null && item.SearchObjArr.Any())
                        {
                            resData.Add(item.Field, item.SearchObjArr);
                        }
                    }
                    else
                    {
                        if (!string.IsNullOrEmpty(item.SearchStr))
                        {
                            resData.Add(item.Field, item.SearchStr);
                        }
                    }
                }
            }
            var url = input.Url.StartsWith("/") ? $"{_configuration["ReportApiUrl"]}{input.Url}" : 
                $"{_configuration["ReportApiUrl"]}/{input.Url}";
            var reqData = JsonConvert.SerializeObject(resData);
            var headers = new Dictionary<string, string>
            {
                { "Authorization", input.Authorization }
            };
            var res = await _nPRestHttp.PostAsync(url, reqData, headers);
            return res;
        }

        /// <summary>
        /// 导出子表数据
        /// </summary>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public async Task<byte[]> ExportSubDataList(GetCommonApprovalProcessInput input)
        {
            if (input == null || string.IsNullOrEmpty(input.Url))
            {
                throw new Exception("传参错误");
            }

            var resData = new Dictionary<string, object>
            {
                { "PageIndex", input.PageIndex },
                { "PageSize", input.PageSize }
            };
            if (input.SearchItems != null && input.SearchItems.Any())
            {
                foreach (var item in input.SearchItems)
                {
                    if (resData.ContainsKey(item.Field))
                    {
                        continue;
                    }

                    if (item.FieldType?.ToLower() == "date")
                    {
                        if (!string.IsNullOrEmpty(item.StartTime) && !string.IsNullOrEmpty(item.EndTime) &&
                        DateTime.TryParse(item.StartTime, out DateTime StartTime) && DateTime.TryParse(item.EndTime, out DateTime EndTime))
                        {
                            resData.Add(item.Field, new List<DateTime>() { StartTime, EndTime });
                        }
                    }
                    else if (item.FieldType?.ToLower() == "select-multiple")
                    {
                        if (item.SearchObjArr != null && item.SearchObjArr.Any())
                        {
                            resData.Add(item.Field, item.SearchObjArr);
                        }
                    }
                    else
                    {
                        if (!string.IsNullOrEmpty(item.SearchStr))
                        {
                            resData.Add(item.Field, item.SearchStr);
                        }
                    }
                }
            }
            var url = input.Url.StartsWith("/") ? $"{_configuration["ReportApiUrl"]}{input.Url}" :
                $"{_configuration["ReportApiUrl"]}/{input.Url}";
            var reqData = JsonConvert.SerializeObject(resData);
            var headers = new Dictionary<string, string>
            {
                { "Authorization", input.Authorization },
            };

            RestClient client = new RestClient();
            
            var req = new RestRequest(url, Method.POST);
            req.AddJsonBody(reqData);
            req.AddHeaders(headers);
            var result = client.DownloadData(req);

            return result;
        }
    }
}
